package helper

import (
	"fmt"
	"github.com/valyala/fasthttp"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protoreflect"
	"time"
)

var (
	fc          = &fasthttp.Client{}
	rpc_url     string
	rpc_timeout time.Duration
)

func HttpDoTimeout(requestBody []byte, method string, requestURI string, headers map[string]string, timeout time.Duration) ([]byte, int, error) {

	req := fasthttp.AcquireRequest()
	resp := fasthttp.AcquireResponse()

	defer func() {
		fasthttp.ReleaseResponse(resp)
		fasthttp.ReleaseRequest(req)
	}()

	req.SetRequestURI(requestURI)
	req.Header.SetMethod(method)

	switch method {
	case "POST", "PUT", "DELETE":
		req.SetBody(requestBody)
	}

	if headers != nil {
		for k, v := range headers {
			req.Header.Set(k, v)
		}
	}

	// time.Second * 30
	err := fc.DoTimeout(req, resp, timeout)

	return resp.Body(), resp.StatusCode(), err
}

func RPCInit(uri string, timeout time.Duration) {
	rpc_url = uri
	rpc_timeout = timeout
}

func RPCCall(name string, req protoreflect.ProtoMessage, resp protoreflect.ProtoMessage) error {

	header := map[string]string{
		"Content-Type": "application/x-www-form-urlencoded",
		"X-Func":       name,
	}

	data, err := proto.Marshal(req)
	if err != nil {
		return err
	}

	body, status, err := HttpDoTimeout(data, "POST", rpc_url+name, header, rpc_timeout)
	if err != nil {
		return err
	}
	if status != 200 {
		return fmt.Errorf("status %d", status)
	}

	err = proto.Unmarshal(body, resp)
	if err != nil {
		return err
	}

	return nil
}
